package com.ruoyi.common.utils;

import java.lang.reflect.Field;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.HashSet;
import java.util.Arrays;

public class ObjectFieldUtils {

    /**
     * 判断对象所有属性是否全为空（忽略指定字段）
     * @param obj 要检查的对象
     * @param includePrimitives 是否将基本类型的默认值(0/false)视为空
     * @param ignoreFields 要忽略的字段名（不参与空值检查）
     * @return 所有非忽略字段为空返回true，否则false
     */
    public static boolean isAllFieldsNull(Object obj, 
                                         boolean includePrimitives, 
                                         String... ignoreFields) {
        if (obj == null) {
            return true;
        }
        
        // 将忽略字段转换为Set便于快速查找
        Set<String> ignoreSet = new HashSet<>(Arrays.asList(ignoreFields));

        Class<?> clazz = obj.getClass();
        while (clazz != null && clazz != Object.class) {
            for (Field field : clazz.getDeclaredFields()) {
                String fieldName = field.getName();
                
                // 跳过忽略字段
                if (ignoreSet.contains(fieldName)) {
                    continue;
                }
                
                // 跳过静态字段
                if (java.lang.reflect.Modifier.isStatic(field.getModifiers())) {
                    continue;
                }
                
                field.setAccessible(true);
                try {
                    Object value = field.get(obj);
                    // 检查字段是否为空
                    if (!isEmpty(value, field.getType(), includePrimitives)) {
                        return false;
                    }
                } catch (IllegalAccessException e) {
                    throw new RuntimeException("检查字段值时出错: " + fieldName, e);
                }
            }
            clazz = clazz.getSuperclass(); // 检查父类字段
        }
        return true;
    }

    /**
     * 判断单个值是否为空
     */
    private static boolean isEmpty(Object value, Class<?> type, boolean includePrimitives) {
        // 处理基本数据类型
        if (type.isPrimitive()) {
            if (!includePrimitives) return false; // 基本类型默认不算空
            return isPrimitiveDefault(value, type);
        }

        // 处理引用类型
        if (value == null) return true;
        
        // 字符串类型
        if (value instanceof CharSequence) {
            return ((CharSequence) value).length() == 0;
        }
        
        // 集合类型
        if (value instanceof Collection) {
            return ((Collection<?>) value).isEmpty();
        }
        
        // Map类型
        if (value instanceof Map) {
            return ((Map<?, ?>) value).isEmpty();
        }
        
        // 数组类型
        if (value.getClass().isArray()) {
            return Array.getLength(value) == 0;
        }
        
        // 其他对象类型
        return false;
    }

    /**
     * 检查基本类型是否为默认值
     */
    private static boolean isPrimitiveDefault(Object value, Class<?> type) {
        if (int.class == type) return (int) value == 0;
        if (long.class == type) return (long) value == 0L;
        if (double.class == type) return (double) value == 0.0;
        if (float.class == type) return (float) value == 0.0f;
        if (boolean.class == type) return !(boolean) value;
        if (char.class == type) return (char) value == '\u0000';
        if (byte.class == type) return (byte) value == 0;
        if (short.class == type) return (short) value == 0;
        return false;
    }
}